﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Axe.Imaging
{
    public static class ImageHelper
    {
        public static string GetImageMimeType(Image img)
        {
            ImageCodecInfo[] decs = ImageCodecInfo.GetImageDecoders();
            
            for(int i=0;i<decs.Length;i++)
            {
                if (img.RawFormat.Guid == decs[i].FormatID)
                    return decs[i].MimeType;
            }

            throw new ArgumentException("Unsupported image format");
        }

        public static byte[] ToBytes(Image img, ImageFormat fmt)
        {
            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    img.Save(ms, fmt);
                    byte[] data = ms.ToArray();
                    return data;
                }
            }
            catch
            {
                return new byte[0];
            }
        }
        public static Image FromBytes(byte[] img)
        {
            try
            {
                if(img == null)
                    return new Bitmap(16, 16);

                using (MemoryStream ms = new MemoryStream(img, false))
                {
                    return Image.FromStream(ms);
                }
            }
            catch
            {
                return new Bitmap(16,16);
            }
        }

        public static void BitBit(Bitmap src, Bitmap dst, int posX, int posY)
        {
            for (int y = 0; y < src.Height; y++)
            {
                for (int x = 0; x < src.Width; x++)
                {
                    Color c = src.GetPixel(x, y);
                    if (c != Color.Transparent)
                    {
                        dst.SetPixel(x + posX, y + posY, c);
                    }
                }
            }
        }


        public static bool ConvertToPng(string sourceFile, string destFile)
        {
            try
            {
                using (Image source = Image.FromFile(sourceFile))
                {
                    if (source.RawFormat == ImageFormat.Png)
                        File.Copy(sourceFile, destFile);
                    else
                        source.Save(destFile, ImageFormat.Png);
                }

                return true;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                return false;
            }
        }

        public static Image Thumbnail(Image sourceImg, int width, int height, bool saveProprtions, Color backColor)
        {
            if (width <= 0)
                throw new ArgumentException(Axe_Exceptions.InvalidImageThumbWidth);

            if (height <= 0)
                throw new ArgumentException(Axe_Exceptions.InvalidImageThumbHeight);

            if (saveProprtions)
            {
                float imageAspect = (float)sourceImg.Width / (float)sourceImg.Height;

                float thumbAspect = (float)width / (float)height;

                if (imageAspect != thumbAspect)
                {
                    float scaleWidth = (float)sourceImg.Width / (float)width;
                    float scaleHeight = (float)sourceImg.Height / (float)height;

                    float usedScale = Math.Max(scaleHeight, scaleWidth);

                    int thumbWidth = (int)(sourceImg.Width / usedScale);
                    int thumbHeight = (int)(sourceImg.Height / usedScale);

                    int x = Math.Max(width - thumbWidth, 0) / 2;
                    int y = Math.Max(height - thumbHeight, 0) / 2;

                    Image readyThumb = new Bitmap(width, height, PixelFormat.Format32bppArgb);

                    using (Image tmpThumb = sourceImg.GetThumbnailImage(thumbWidth, thumbHeight, null, IntPtr.Zero))
                    {
                        using (Graphics gr = Graphics.FromImage(readyThumb))
                            gr.Clear(backColor);

                        ImageHelper.BitBit((Bitmap)tmpThumb, (Bitmap)readyThumb, x, y);
                    }
                    return readyThumb;
                }
            }
            
            return sourceImg.GetThumbnailImage(width, height,null, IntPtr.Zero);
        }


        /// <summary>
        /// Пробуем разобрать указанный путь к файлу и на основании расширения файла "узнать" формат изображения.
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static bool GetImageFormatByExtension(string fileName, ref ImageFormat format)
        {
            string ext = Path.GetExtension(fileName);
            if (String.IsNullOrEmpty(ext))
            {
                return false;
            }

            ext = ext.ToLower();

            switch (ext)
            {
                case "bmp":
                    format = ImageFormat.Bmp; return true;

                case "ico":
                    format = ImageFormat.Icon; return true;

                case "gif":
                    format = ImageFormat.Gif; return true;

                case "jpg":
                case "jpeg":
                    format = ImageFormat.Jpeg; return true;

                case "png":
                    format = ImageFormat.Png; return true;

                case "emf":
                    format = ImageFormat.Emf; return true;

                case "tiff":
                    format = ImageFormat.Tiff; return true;

                case "wmf":
                    format = ImageFormat.Wmf; return true;

                case "exif":
                    format = ImageFormat.Exif; return true;
                default:
                    return false;
            }
        }
    }
}
